﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using PSIEpics;
//using string_short;
using System.Threading;
using EpicsJecket;
using JtextEpicsInterface;

using System.Text.RegularExpressions;
using JTextSdd;
//using EJServer_driver;

namespace SerialPortServerTester
{
    class Program
    {
        //const string SERVERNAME = "SSFC_01";    //super sonic fueling control
        //const string CLIENTNAME = "SSFC_Clinet_01";
        //const string PV_SERVERSTAT = "STI:SSFC:STATE01";


        #region additionnal
        /// <summary>
        /// make a string that contains many hex numbers splited by spliter to byte[]
        /// </summary>
        /// <param name="HexString">The hex string.</param>
        /// <param name="spliter">The spliter.</param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string HexString, string spliter)
        {
            byte[] tBytes;
            string[] tVals = Regex.Split(HexString, spliter, RegexOptions.IgnoreCase);
            tBytes = new byte[tVals.Length];
            for (int i = 0; i < tVals.Length; i++)
            {
                tBytes[i] = Convert.ToByte(tVals[i], 16);
            }
            return tBytes;
        }

        /// <summary>
        /// make byte array to a string .
        /// </summary>
        /// <param name="BytesArray">The bytes array.</param>
        /// <param name="spliter">The spliter.</param>
        /// <returns></returns>
        public static string BytesToHexString(byte[] BytesArray, string spliter)
        {
            string StrOut = "";
            for (int m = 0; m < BytesArray.Length; m++)
            {
                StrOut = StrOut + (BytesArray[m].ToString("X2") + spliter);
            }
            return StrOut;
        }

        #endregion



        #region server_envent

        /// <summary>
        /// server recieve msg from client
        /// </summary>
        /// <param name="msg">The MSG.</param>
        public static  void PrintMsg(object msg, bool isByte, EJServer.Reply_to From_whog)
        {
            string Str_msg;
            if (isByte == true)
            {

                Str_msg = BytesToHexString((byte[])msg, " ");
            }
            else
            {
                Str_msg = (string)msg;
            }
            //Console.WriteLine("ass");
            Console.WriteLine(From_whog.ToString()+" : "+ Str_msg);
        }

        #endregion


        static void Main(string[] args)
        {
            #region Version 1.0
            //EJServer myserver = new EJServer(SERVERNAME,true,5,0,EJServer.Reply_to.Scanner,null);
            //myserver.addScanVarible(PV_SERVERSTAT, 2, 0, -1,1);
            ////myserver.addScanVarible("p2", 2, 0, -1);
            //myserver.ScanCmd = new byte[5] { 0x55, 0x01, 0x00, 0x26, 0x26 };
            //myserver.StartServer();
            //myserver.StartScan(700);
            ////string a="1";


            //while (true)
            //    Console.ReadKey(); ;
            #endregion


            #region version 2.0
            /*
            EJServer myserver = new EJServer(SERVERNAME, true, 5, 0, EJServer.Reply_to.Scanner);
            myserver.LoadDrivers(AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\EJServer_driver2.dll", "SerialPort", "com4;9600;1;0");
            myserver.addScanVarible(PV_SERVERSTAT, 2, 0, -1, 1);
            //myserver.addScanVarible("p2", 2, 0, -1);
            myserver.ScanCmd = new byte[5] { 0x55, 0x01, 0x00, 0x26, 0x26 };
            myserver.ScanDefaultReply = new byte[5] { 0x55, 0x01, 0xFF, 0x26, 0x26 };
            myserver.ConsoleOut = true;
            JEDevice myDev = new JEDevice("DEV:TEST:EJ", "null", true, null);
            myDev.PublishDevice();

            myserver.StartServer();
            myserver.StartScan(700);
            //string a="1";


            while (true)
                Console.ReadKey(); ;
             * */
            #endregion

            #region version 3.0 sdd support

            Console.WriteLine("This is a ganerel purpose EpicsJacket Server with JtextSDD support.");
            Console.WriteLine("2011_06_20  Jtext Control Team");

            Console.WriteLine("sdd file name as a argument");
            Console.WriteLine("2011-11-08");
            Console.WriteLine("11111111 special edition with bug fixed now support spliter.");
            Console.WriteLine("2011-11-11");
            string WorkingPath = AppDomain.CurrentDomain.BaseDirectory.ToString();


            string SDDFileName;
            //create sdd object
            try
            {
                SDDFileName = args[0];
            }
            catch
            {
                SDDFileName = "sdd.xml";    //use default sdd files
            }
            SDDtoEpics mySdd = new SDDtoEpics(WorkingPath + SDDFileName);


            string ServerName = mySdd.servername;
            bool isByte = mySdd.isByte;
            int msgLen = mySdd.messageLen;
            byte ending = mySdd.ending;
            int reply_To = mySdd.ReplyTo;
            string Scanner = mySdd.scanner;
            string DefScennerReply = mySdd.DefaultScanner;
            string[] MsgDriver = mySdd.DriverMessage();
            string Spliter = mySdd.Spliter;
            //ordor[DriverFlie,DriverName,DriverPath,timeout,timeoutlimit];

            //EJServer myserver = new EJServer(SERVERNAME, true, 5, 0, EJServer.Reply_to.Scanner);
            EJServer myserver = new EJServer(ServerName, isByte, msgLen, ending, (EJServer.Reply_to)reply_To);
            myserver.ConsoleOut = true;

            myserver.LoadDrivers(AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\" + MsgDriver[0], MsgDriver[1], MsgDriver[2]);
            myserver.WatchdogTimeout = Convert.ToInt16(MsgDriver[3]);
            myserver.TimeOutTimesLimit = Convert.ToInt16(MsgDriver[4]);
            #region ini scan

            //myserver.addScanVarible(PV_SERVERSTAT, 2, 0, -1, 1);
            //myserver.addScanVarible("p2", 2, 0, -1);

            MessageProp[] MyMsgPropS = mySdd.getAllMessageprop();
            foreach (MessageProp MyMsgProp in MyMsgPropS)
            {
                myserver.addScanVarible(MyMsgProp);
                Console.WriteLine("add pv:"  + MyMsgProp.pvName);
            }

            if (isByte == true)
            {
                myserver.ScanCmd = HexStringToBytes(Scanner, " ");
                myserver.ScanDefaultReply = HexStringToBytes(DefScennerReply, " ");

            }
            else
            {
                myserver.ScanCmd = Scanner;
                myserver.ScanDefaultReply = DefScennerReply;
                if (Spliter != "")
                {
                    myserver.Spliter = Spliter;
                }
            }

            #endregion

            //JEDevice myDev = new JEDevice("DEV:TEST:EJ", "null", true, null);
            //myDev.PublishDevice();

            myserver.OnOutMessage += new EJServer.OutMessageHandler(PrintMsg);

            myserver.StartServer();
            myserver.StartScan(((int)mySdd.scaninterval));
            //string a="1";


            while (true)
                Console.ReadKey(); ;
            #endregion







        }
    }
}
